package com.taihe.util.wechat;


import com.taihe.constants.WeiXinConstants;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.UUID;

/**
 * Created by zwt on 2018/1/25.
 *
 * 微信公众号相关通用工具类
 */
public class CommonUtils {

    private static Logger logger = LoggerFactory.getLogger(CommonUtils.class);



    /**
     * 获取接口访问凭证  普通的
     * @param appId
     * @param appSecret
     * @return
     */
    public static AccessToken getAccesstoken(String appId, String appSecret){
        AccessToken accessToken = null;
        String requestUrl = WeiXinConstants.ACCESS_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret);
        JSONObject jsonObject = HttpUtils.httpsRequest(requestUrl, "GET", null);
        if(null!=jsonObject){
            try {
                accessToken = new AccessToken();
                accessToken.setAccessToken(jsonObject.getString("access_token"));
                accessToken.setExprie(jsonObject.getInt("expires_in"));
            } catch (Exception e) {
                logger.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return accessToken;
    }


    /**
     * 获取授权凭证
     * @param appId
     * @param appSecret
     * @param code
     * @return
     */
    public static WeixinOAuth2AccessToken getWeixinOAuth2AccessToken(String appId, String appSecret, String code){
        WeixinOAuth2AccessToken weixinOAuth2AccessToken = null;
        String requestUrl = WeiXinConstants.OAYTH2_ACCESS_TOKEN_URL.replace("APPID", appId).replace("APPSECRET", appSecret).replace("CODE",code);
        JSONObject jsonObject = HttpUtils.httpsRequest(requestUrl, "GET", null);
        logger.error("获取WeixinOAuth2AccessToken返回的jsonObject=="+jsonObject);
        if(null!=jsonObject){
           try {
               weixinOAuth2AccessToken = new WeixinOAuth2AccessToken();
               weixinOAuth2AccessToken.setAccessToken(jsonObject.getString("access_token"));
               weixinOAuth2AccessToken.setExpiresIn(jsonObject.getInt("expires_in"));
               weixinOAuth2AccessToken.setOpenId(jsonObject.getString("openid"));
               weixinOAuth2AccessToken.setScope(jsonObject.getString("scope"));
               weixinOAuth2AccessToken.setRefreshToken(jsonObject.getString("refresh_token"));
           } catch (Exception e){
               logger.error("获取网页授权凭证失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
           }
        }
        return weixinOAuth2AccessToken;
    }


    /**
     * 获取微信用户信息
     * @param weiXinOAuth2AccessToken
     * @param openId
     * @return
     */
    public static WeiXinUser getWeiXinUser(String weiXinOAuth2AccessToken, String openId){
        WeiXinUser weiXinUser = null;
        String requestUrl = WeiXinConstants.WEIXINUSER_URL.replace("ACCESS_TOKEN",weiXinOAuth2AccessToken).replace("OPENID",openId);
        JSONObject jsonObject = HttpUtils.httpsRequest(requestUrl, "GET", null);
        if(null!=jsonObject){
            try{
                weiXinUser = new WeiXinUser();
                weiXinUser.setOpenId(jsonObject.getString("openid"));
                weiXinUser.setCity(jsonObject.getString("city"));
                weiXinUser.setCountry(jsonObject.getString("country"));
                weiXinUser.setProvince(jsonObject.getString("province"));
                weiXinUser.setSex(jsonObject.getInt("sex")); // 1 男性 2 女性 0 未知
                weiXinUser.setHeadImgUrl(jsonObject.getString("headimgurl"));
                weiXinUser.setNickname(jsonObject.getString("nickname"));
            }catch (Exception e){
                logger.error("获取微信用户信息 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
            }
        }
        return weiXinUser;
    }

    /**
     * 获取jsApiTicket
     * @param appId
     * @param appSecret
     * @return
     */
    public static String getJSApiTicket(String appId, String appSecret){
        AccessToken accesstoken = CommonUtils.getAccesstoken(appId, appSecret);
        if(null!=accesstoken){
            String requestUrl = WeiXinConstants.JSAPITCKET_URL.replace("ACCESS_TOKEN",accesstoken.getAccessToken());
            JSONObject jsonObject = HttpUtils.httpsRequest(requestUrl, "GET", null);
            String ticket = jsonObject.getString("ticket");
            return ticket;
        }
       return null;
    }

    /**
     * 获取微信的配置信息
     * @param request
     * @param appId
     * @param appSecret
     * @return
     */
    public static WxConfig getWxConfig(HttpServletRequest request, String jsapiTicket , String appId, String appSecret){
        WxConfig wxConfig = new WxConfig();
        String requestUrl = request.getRequestURL().toString();
        String queryurl=request.getQueryString();
        if(null!=queryurl){
            requestUrl+="?"+queryurl;
        }
        String signature = "";
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填，生成签名的时间戳
        String nonceStr = UUID.randomUUID().toString(); // 必填，生成签名的随机串
        String sign = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr+ "&timestamp=" + timestamp + "&url=" + requestUrl;
        try {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(sign.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
            wxConfig.setSignature(signature);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        wxConfig.setAppId(appId);
        wxConfig.setJsapiTicket(jsapiTicket);
        wxConfig.setNonceStr(nonceStr);
        wxConfig.setTimestamp(timestamp);
        return wxConfig;
    }

    /**
     * 方法名：byteToHex</br>
     * 详述：字符串加密辅助方法 </br>
     * 开发人员：souvc  </br>
     * 创建时间：2016-1-5  </br>
     * @param hash
     * @return 说明返回值含义
     * @throws
     */
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;

    }

    public static String generateUrl(HttpServletRequest request){
        String forwordUrl="http://" + request.getServerName() //服务器地址
//                + ":"
//                + request.getServerPort()           //端口号
                + request.getRequestURI();
        logger.error("forwordUrl=="+forwordUrl);
        String queryurl=request.getQueryString();
        logger.error("queryurl=="+queryurl);
        if(null!=queryurl){
            forwordUrl+="?"+queryurl;
        }
        try {
            forwordUrl = java.net.URLEncoder.encode(forwordUrl, "utf-8");
            logger.error("编码格式化的forwordUrl=="+forwordUrl);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+WeiXinConstants.APPID+"&redirect_uri="+forwordUrl+"&response_type=code&scope=snsapi_userinfo&state=1517291445&connect_redirect=1#wechat_redirect";
        logger.error("url=="+url);
        return url;
    }

}
